/*
 * Copyright (c) 2012, Tony Houghton <h@realh.co.uk>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

// HGame - a simple cross-platform game framework

#include "hgame/RendererWithState.h"

namespace hgame {

RendererWithState::RendererWithState(ThreadFactory *tf, Log *log) :
        mLog(*log),
        mCurrentRenderState(RENDER_STATE_UNINITIALISED),
        mRequestedRenderState(RENDER_STATE_UNINITIALISED),
        mRenderStateMutex(tf->createMutex())
{
}

RendererWithState::~RendererWithState()
{
    delete mRenderStateMutex;
}

void RendererWithState::requestRenderState(RenderState new_state)
{
    mRenderStateMutex->lock();
    mRequestedRenderState = new_state;
    mRenderStateMutex->unlock();
}

void RendererWithState::serviceRenderRequest(RenderContext *rc)
{
    mRenderStateMutex->lock();
    if (mRequestedRenderState == RENDER_STATE_REPLACE_SCREEN)
    {
        replaceRenderingScreen(rc);
    }
    if ((mRequestedRenderState == RENDER_STATE_INITIALISED ||
            mRequestedRenderState == RENDER_STATE_RENDERING) &&
            mCurrentRenderState == RENDER_STATE_UNINITIALISED)
    {
        initRendering(rc);
    }
    if (mRequestedRenderState == RENDER_STATE_RENDERING)
    {
        render(rc);
        rc->flipBuffers();
    }
    if (mRequestedRenderState == RENDER_STATE_UNINITIALISED &&
            (mCurrentRenderState == RENDER_STATE_INITIALISED ||
            mCurrentRenderState == RENDER_STATE_RENDERING))
    {
        deleteRendering(rc);
    }
    if (mRequestedRenderState == RENDER_STATE_RESIZE)
    {
        resizeRendering(rc);
        mRequestedRenderState = mCurrentRenderState;
    }
    else if (mRequestedRenderState != RENDER_STATE_REPLACE_SCREEN)
    {
        mCurrentRenderState = mRequestedRenderState;
    }
    mRenderStateMutex->unlock();
}

}
